/**
 * @file STL_ModLog.cpp
 * @author Derek Liu (yjkhtddx@sina.com)
 * @brief 
 * @version 0.1
 * @date 2021-07-26
 * 
 * @copyright Copyright (c) 2021
 * 
 */

#include "STL_ModLog.h"

namespace STL
{
    STL_ModLog::STL_ModLog() : m_tag(""), m_level(STL::STL_ModLog::STL_ModLog_Debug), m_logCallback(nullptr), m_timestampFormat("%F %T:%s")
    {
    }

    STL_ModLog::STL_ModLog(std::string tag) : m_tag(tag), m_level(STL::STL_ModLog::STL_ModLog_Debug), m_logCallback(nullptr), m_timestampFormat("%F %T:%s"), m_color(false)
    {
    }

    STL_ModLog::~STL_ModLog()
    {
    }

    void STL_ModLog::stl_modlog(STL_ModLog::Level level, const char *format, ...)
    {
        if (level < m_level)
            return;

        std::string fmt = "";

        if (m_color)
        {
            fmt.append(std::string(STLOG_ESC_START));
            switch (level)
            {
            case STL_ModLog::STL_ModLog_Fatal:
                fmt.append(std::string(STLOG_COLOR_FATAL));
                break;
            case STL_ModLog::STL_ModLog_Error:
                fmt.append(std::string(STLOG_COLOR_ERROR));
                break;
            case STL_ModLog::STL_ModLog_Warn:
                fmt.append(std::string(STLOG_COLOR_WARN));
                break;
            case STL_ModLog::STL_ModLog_Info:
                fmt.append(std::string(STLOG_COLOR_INFO));
                break;
            case STL_ModLog::STL_ModLog_Debug:
                fmt.append(std::string(STLOG_COLOR_DEBUG));
                break;
            case STL_ModLog::STL_ModLog_Trace:
            default:
                fmt.append(std::string(STLOG_COLOR_TRACE));
                break;
            }
        }

        fmt.append("[");
        fmt.append(m_tag);
        fmt.append("] ");
        fmt.append(getTimestampString(m_timestampFormat));
        switch (level)
        {
        case STL_ModLog::STL_ModLog_Fatal:
            fmt.append(std::string(" FATAL "));
            break;
        case STL_ModLog::STL_ModLog_Error:
            fmt.append(std::string(" ERROR "));
            break;
        case STL_ModLog::STL_ModLog_Warn:
            fmt.append(std::string(" WARN  "));
            break;
        case STL_ModLog::STL_ModLog_Info:
            fmt.append(std::string(" INFO  "));
            break;
        case STL_ModLog::STL_ModLog_Debug:
            fmt.append(std::string(" DEBUG "));
            break;
        case STL_ModLog::STL_ModLog_Trace:
        default:
            fmt.append(std::string(" TRACE "));
            break;
        }
        fmt.append(std::string("[%s:%d %s()] => "));
        fmt.append(std::string(format));
        fmt.append(std::string(STLOG_ESC_END));
        if (m_color)
        {

            fmt.append(std::string(STLOG_COLOR_LEND));
        }

        va_list args, vl;
        va_start(args, format); //第二个参数是...之前的参数
        va_copy(vl, args);
        // vprintf(fmt.c_str(), args);
        va_end(args);

        if (m_logCallback)
        {
            char temp[1024 * 1024] = {0};
            vsnprintf(temp, 1024 * 1024 - 1, fmt.c_str(), vl);
            m_logCallback(m_tag, level, std::string(temp));
        }

        va_end(vl);
    };
}
